package com.crazyimp.utilities;

import java.io.InputStream;
import java.util.Stack;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;

public class Downloader{
	
	//private static int MAX_STACK_SIZE = 10;
	
	private Stack<Request> stack;
	private volatile boolean stop;
	private final HttpClient httpclient;
	private Thread thread;
	private volatile boolean started = false;
	private Runnable download = new Runnable(){
		@Override
		public void run() {
			while(!stop && !stack.isEmpty()){
				startModify();
				final Request request = stack.pop();
				if (request != null){
					final InputStream is = download(request.address);
					if (!stop && is != null){
						if (request.listener != null)
							request.listener.onDownload(request.requestCode, is);
					}
					else
						stack.add(request);
				}
				stopModify();
			}
		}
	};
	private volatile boolean modify = true;
	
	public Downloader(){
		stack = new Stack<Request>();
		
		stop = false;
		httpclient = new DefaultHttpClient();
		thread = new Thread(download);
		thread.setDaemon(true);
	}
		
	private class Request {
		public int requestCode;
		public String address;
		public IDownloadListener listener;
	}
	
	/**
	 * 
	 * @param requestCode
	 * @param address
	 * @param listener
	 */	
	public void addRequest(final int requestCode, final String address, final IDownloadListener listener){
		final Request request = new Request();
		request.address = address;
		request.requestCode = requestCode;
		request.listener = listener;
		stack.add(request);
		/*startModify();
		if (MAX_STACK_SIZE < stack.size()){
			final Request cut = stack.lastElement();			
			if (cut != null){
				cut.listener.onDownload(cut.requestCode, null);
			}
			stack.setSize(MAX_STACK_SIZE);
		}
		stopModify();
		*/
		if (!thread.isAlive()){
			startThread();
		}
	}
	
	private InputStream download(final String address){
		InputStream is = null;
		try {		
			HttpPost httppost = new HttpPost(address);
	        HttpResponse response = httpclient.execute(httppost);
	        HttpEntity entity = response.getEntity();
	        is = entity.getContent();
		} catch (Exception e){}		
		return is;
	}

	public void stopDownloader(){
		stop = true;
	}
	
	public synchronized void startDownloader(){
		if (!stack.isEmpty() && !thread.isAlive()){
			startThread();
		}
	}
	
	private void startThread(){
		if (started){
			thread = new Thread(download);
			thread.setDaemon(true);
			thread.start();
		} else {
			started = true;
			thread.start();
		}
	}
	
	public synchronized void startModify(){
		while(!modify){}
		modify = false;
	}
	
	public void stopModify(){
		modify = true;
	}
	
}
